package sql.ddl;

import java.util.ArrayList;
import java.util.List;

import sql.ddl.coluna.Coluna;
import sql.ddl.coluna.ColunaComposta;
import sql.ddl.coluna.ListaColuna;
import sql.ddl.coluna.types.Serial;

public class Tabela implements TokensSQL {
	String nome = null;

	boolean pkDefault = false;

	Schema schema = null;

	ListaColuna colunas = null;

	PrimaryKey chave = null;

	List<Unique> unicidades = null;

	public Tabela(String nome) {
		this.nome = nome;
	}

	public Tabela(String nome, boolean pkDefault) {
		this(nome);
		this.pkDefault = pkDefault;
		chave = new PrimaryKey(new Serial(PK + nome, NOT + SPACE + NULL));
		chave.setConstraint(nome.toUpperCase() + "_CHAVE");

	}

	public PrimaryKey getPrimaryKey() throws Exception {
		if (chave == null)
			throw new Exception("A Tabela " + nome + " Não Possui KEY");
		return chave;
	}

	public String codigoSQL() {
		String sUnique = unicidades != null ? uniques() : NONVALUE;
		return CREATE + SPACE + TABLE + SPACE + realName() + BEGINPARENTES
				+ colunas() + primaryKey() + foreignKey() + sUnique
				+ ENDPARENTES;
	}

	private String uniques() {
		String vUnicidades = NONVALUE;
		for (Unique u : unicidades)
			vUnicidades += VIRGUL + u.codigoSQL();
		return vUnicidades;
	}

	private String realName() {
		return (schema == null ? NONVALUE : schema + PONTO) + nome;
	}

	private String foreignKey() {
		String slqForeignKey = NONVALUE;
		try {
			for (Coluna c : colunas)
				try {
					ColunaComposta cc = (ColunaComposta) c;
					slqForeignKey += (VIRGUL + cc.getForeignKey().codigoSQL());
				} catch (Exception e) {
				}
		} catch (Exception e) {
			// não possui colunas
		}
		return slqForeignKey;
	}

	private String primaryKey() {
		return chave != null ? VIRGUL + chave.codigoSQL() : NONVALUE;
	}

	private String colunas() {
		try {
			return getALLColunas() == null || getALLColunas().isEmpty() ? NONVALUE
					: getALLColunas().codigoSQL();
		} catch (Exception e) {
			e.printStackTrace();
			return NONVALUE;
		}
	}

	public void addColuna(Coluna coluna) {
		colunas = colunas == null ? new ListaColuna() : colunas;
		colunas.add(coluna);
	}

	public void setPrimaryKey(PrimaryKey key) {
		chave = key;
	}

	public String getALLName() {
		return (schema == null ? NONVALUE : schema + PONTO) + nome;
	}

	public void setSchema(Schema schema) {
		this.schema = schema;
	}

	public String getNome() {
		return nome;
	}

	public ListaColuna getALLColunas() {
		ListaColuna cls = new ListaColuna();
		try {
			for (Coluna coluna : chave.getColunas())
				cls.add(coluna);
		} catch (Exception e) {
		}
		try {
			for (Coluna coluna : this.colunas)
				cls.add(coluna);
		} catch (Exception e) {
		}

		return cls;
	}

	public boolean isPkDefault() {
		return pkDefault;
	}

	public Schema getSchema() {
		return schema;
	}

	public void addUNIQUE(Unique unique) {
		unicidades = unicidades == null ? new ArrayList<Unique>() : unicidades;
		unicidades.add(unique);
	}

}
